package com.mpgame.database.mysql.utils;

import com.mpgame.database.mysql.config.MySqlCfg;
import com.mpgame.utils.Log;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class DataSourceUtil {
    private static final Map<String, HikariDataSource> dataSources = new ConcurrentHashMap<>();
    private static final Map<String, Boolean> initializedDatabases = new ConcurrentHashMap<>();
    
    public static void init(MySqlCfg config, String databaseName) {
        if (initializedDatabases.getOrDefault(databaseName, false)) {
            Log.warn("数据源 " + databaseName + " 已初始化，不可重复初始化！");
            return;
        }
        
        try {
            HikariConfig hikariConfig = new HikariConfig();
            hikariConfig.setJdbcUrl(config.getUrl());
            hikariConfig.setUsername(config.getUsername());
            hikariConfig.setPassword(config.getPassword());
            hikariConfig.setDriverClassName(config.getDriverClassName());
            
            // 连接池配置
            hikariConfig.setMaximumPoolSize(config.getMaximumPoolSize());
            hikariConfig.setMinimumIdle(config.getMinimumIdle());
            hikariConfig.setConnectionTimeout(config.getConnectionTimeout());
            hikariConfig.setIdleTimeout(config.getIdleTimeout());
            hikariConfig.setMaxLifetime(config.getMaxLifetime());
            hikariConfig.setConnectionTestQuery(config.getConnectionTestQuery());
            hikariConfig.setValidationTimeout(config.getValidationTimeout());
            hikariConfig.setInitializationFailTimeout(config.getInitializationFailTimeout());
            hikariConfig.setKeepaliveTime(config.getKeepAliveTime());
            hikariConfig.setLeakDetectionThreshold(config.getLeakDetectionThreshold());
            
            // 连接池名称
            hikariConfig.setPoolName(databaseName + "-pool");
            
            HikariDataSource dataSource = new HikariDataSource(hikariConfig);
            dataSources.put(databaseName, dataSource);
            initializedDatabases.put(databaseName, true);
            
            Log.info("数据源 " + databaseName + " 初始化成功: " + config.getUrl());
        } catch (Exception e) {
            Log.err("数据源 " + databaseName + " 初始化失败: " + e.getMessage());
            throw new RuntimeException("数据源 " + databaseName + " 初始化失败", e);
        }
    }
    
    public static DataSource getDataSource(String databaseName) {
        if (!initializedDatabases.getOrDefault(databaseName, false)) {
            throw new RuntimeException("数据源 " + databaseName + " 未初始化，请先调用init方法");
        }
        return dataSources.get(databaseName);
    }
    
    public static Connection getConnection(String databaseName) throws SQLException {
        DataSource dataSource = getDataSource(databaseName);
        return dataSource.getConnection();
    }
    
    public static void closeAll() {
        for (Map.Entry<String, HikariDataSource> entry : dataSources.entrySet()) {
            try {
                entry.getValue().close();
                Log.info("数据源 " + entry.getKey() + " 已关闭");
            } catch (Exception e) {
                Log.err("关闭数据源 " + entry.getKey() + " 失败: " + e.getMessage());
            }
        }
        dataSources.clear();
        initializedDatabases.clear();
    }
    
    public static boolean testConnection() {
        for (String databaseName : initializedDatabases.keySet()) {
            try (Connection conn = getConnection(databaseName)) {
                if (conn.isValid(5)) {
                    Log.info("数据库 " + databaseName + " 连接测试成功");
                } else {
                    Log.err("数据库 " + databaseName + " 连接测试失败");
                    return false;
                }
            } catch (SQLException e) {
                Log.err("数据库 " + databaseName + " 连接测试异常: " + e.getMessage());
                return false;
            }
        }
        return true;
    }
    public static boolean testConnection(String databaseName) {
        if (!initializedDatabases.getOrDefault(databaseName, false)) {
            Log.err("数据库 " + databaseName + " 未初始化");
            return false;
        }
        
        try (Connection conn = getConnection(databaseName)) {
            if (conn.isValid(5)) {
                Log.info("数据库 " + databaseName + " 连接测试成功");
                return true;
            } else {
                Log.err("数据库 " + databaseName + " 连接测试失败");
                return false;
            }
        } catch (SQLException e) {
            Log.err("数据库 " + databaseName + " 连接测试异常: " + e.getMessage());
            return false;
        }
    }
}
